
#pragma once
// 路由模块
// 实现消息路由的功能
//该模块提供消息路由的功能
#include <iostream>
#include <vector>
#include "Log.hpp"
#include "InetAddr.hpp"


using namespace LogModule;

//要将消息发送给所有人
//除了有发送的消息message
//肯定需要有套接字
//还需要接收方的信息，存放在struct sockadd结构体中,InetAddr结构体已经封装好了

class Routine
{
    private:
    //判断要发送的对象是否存在
    bool IsExit(InetAddr& addr)
    {
        for(auto& user:_online_user)
        {
            if(user==addr)
            return true;
        }
        return false;
    }
    void AddUser(InetAddr& peer)
    {
        LOG(LogLevel::INFO)<<"新增一个用户";
        _online_user.push_back(peer);
    }
    void DeleteUser(InetAddr& addr)
    {
        for(auto it=_online_user.begin();it!=_online_user.end();it++)
        {
            if(*it==addr)
            {
                LOG(LogLevel::INFO)<<"删除一个在线用户: "<<addr.StringAdd();
                _online_user.erase(it);
                break;
            }
        }
    }
public:
    Routine()
    {}
    ~Routine()
    {}
    //实现消息路由功能
    void MessageRoutine(int sockfd,const std::string& message,InetAddr& peer)
    {
        if(!IsExit(peer))
        {
            //不存在就新增
            AddUser(peer);
        }
        //发送的消息
        std::string send_message=peer.StringAdd()+"#"+message;

        //发送给每个人
        for(auto& user:_online_user)
        {
            sendto(sockfd,send_message.c_str(),send_message.size(),0,(const struct sockaddr*)&user.NetAddr(),sizeof(user.NetAddr()));

        }
        //约定：如果用户发送了“QUIT”,那么表示该用户想要退出聊天
        if(message=="QUIT")
        {
            LOG(LogLevel::INFO)<<"删除一个在线用户"<<peer.StringAdd();
            DeleteUser(peer);
        }
    }
private:
    // 只要该用户首次给我发消息，就把该用户保存到vector中
    std::vector<InetAddr> _online_user; // 存储在线用户
};